home *** CD-ROM | disk | FTP | other *** search
/ Aminet 2 / Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso / Aminet / util / misc / Fudgit233.lha / Source / src / parse.y < prev    next >
Encoding:
Lex Description  |  1993-12-14  |  25.4 KB  |  726 lines

  1. %{
  2. #include "symbol.h"
  3. #include "code.h"
  4. #define code(c1)    Ft_code(c1)
  5. #define code2(c1, c2) code(c1); code(c2)
  6. #define code3(c1, c2, c3) code(c1); code(c2); code(c3)
  7.  
  8. #undef DEBUG
  9.  
  10. #ifdef DEBUG
  11. #include <stdio.h>
  12. #define PNUM(a)    fprintf(stderr, "Parse: at address %d\n", a);
  13. #define ARGNO(a)   fprintf(stderr, "Parse: argument no %d\n", a);
  14. #define CODE(a)    fprintf(stderr, "Parse: %s\n", a)
  15. #define CODE2(a, b)    CODE(a); CODE(b);
  16. #define CODE3(a, b, c) CODE(a); CODE(b); CODE(c)
  17. #else
  18. #define PNUM(a)
  19. #define ARGNO(a)
  20. #define CODE(a)
  21. #define CODE2(a, b)
  22. #define CODE3(a, b, c)
  23. #endif
  24. int yyerror(char *);
  25. int yylex(void);
  26. extern int Ft_autosymremove(int);
  27. extern int Ft_more_input(int, char *);
  28. extern int Ft_Inbrace;
  29. extern int Ft_Indef;
  30. extern int Ft_Inproto;
  31. extern int Ft_Inauto;
  32. static char *interprompt = 0;
  33. %}
  34. %union {
  35.     Symbol *sym;
  36.     Inst *inst;
  37.     int narg;
  38.     double val;
  39. }
  40. %token  <sym>   VAR BLTINVAR
  41. %token  <sym>   CONST BLTINCONST
  42. %token  <sym>   STRVAR BLTINSTRVAR
  43. %token  <sym>   STRCONST BLTINSTRCONST
  44. %token  <sym>   STRING
  45. %token  <sym>    UNDEFVEC UNDEFVAR UNDEFSTRVAR
  46. %token  <sym>   VEC AUTOVEC
  47. %token  <sym>   PARAM
  48. %token  <sym>   PRINT WHILE IF ELSE
  49. %token  <sym>   CONTINUE BREAK FOR RETURN FUNC PROC
  50. %token  <sym>    FUNCSYM PROCSYM EFUNCSYM EPROCSYM
  51. %token  <sym>   AUTO ARG AUTOSTRVAR
  52. %token  <sym>   BLTIN0 BLTIN1 BLTIN2 STRBLTIN2 BLTIN1VEC
  53. %token  <sym>   BLTIN0STR BLTIN1STR BLTIN2STR
  54. %token  <narg>  VARARG STRVARARG VECARG PARARG
  55. %token  <val>   NUMBER
  56. %type   <inst>  stmtline dontprint value strvalue
  57. %type   <inst>  expr exprl exprlist stmt varincr prlist
  58. %type   <inst>  asgn asgnl asgnlist forcond strasgn
  59. %type   <inst>  parloop vecloop vecasgn parasgn
  60. %type   <inst>  cond while if begin end for string
  61. %type   <inst>  argstr argvec argexpr opbrace nicevec argpar
  62. %type   <sym>   procname element
  63. %type   <narg>  autol autolist autolines
  64. %type   <narg>  arglist argelement
  65. %right  '=' DIVASS MULASS ADDASS SUBASS
  66. %left   OR
  67. %left   AND
  68. %left   GT GE LT LE EQ NE
  69. %left   '+' '-'
  70. %left   '*' '/' '%'
  71. %left   UNARYMINUS NOT
  72. %right  '^'
  73. %right  INCR DECR
  74. %%
  75. list:
  76.     | list '\n'
  77.     | list defn '\n'
  78.     | list stmtline '\n'    {
  79.             CODE("STOP");
  80.             code(STOP); Ft_execute(Ft_Progbase); return(1); }
  81.     | list error '\n' { yyerrok; }
  82.     ;
  83. stmtline: begin stmt
  84.     |    stmtline ';' stmt
  85.     ;
  86. asgn:    VAR '=' expr     {
  87.             CODE3("varpush", $1->name, "assign");
  88.             code3(Ft_varpush, (Inst)$1, Ft_assign); $$=$3; }
  89.     |    VAR ADDASS expr    {
  90.             CODE3("varpush", $1->name, "addassign");
  91.             code3(Ft_varpush, (Inst)$1, Ft_addassign); $$=$3; }
  92.     |    VAR SUBASS expr    {
  93.             CODE3("varpush", $1->name, "subassign");
  94.             code3(Ft_varpush, (Inst)$1, Ft_subassign); $$=$3; }
  95.     |    VAR MULASS expr    {
  96.             CODE3("varpush", $1->name, "mulassign");
  97.             code3(Ft_varpush, (Inst)$1, Ft_mulassign); $$=$3; }
  98.     |    VAR DIVASS expr    {
  99.             CODE3("varpush", $1->name, "divassign");
  100.             code3(Ft_varpush, (Inst)$1, Ft_divassign); $$=$3; }
  101.     |    VARARG '=' expr     {
  102.             CODE("argassign"); ARGNO($1);
  103.             code2(Ft_argassign, (Inst)$1); $$=$3; }
  104.     |    VARARG ADDASS expr    {
  105.             CODE("argaddassign"); ARGNO($1);
  106.             code2(Ft_argaddassign, (Inst)$1); $$=$3; }
  107.     |    VARARG SUBASS expr    {
  108.             CODE("argsubassign"); ARGNO($1);
  109.             code2(Ft_argsubassign, (Inst)$1); $$=$3; }
  110.     |    VARARG MULASS expr    {
  111.             CODE("argmulassign"); ARGNO($1);
  112.             code2(Ft_argmulassign, (Inst)$1); $$=$3; }
  113.     |    VARARG DIVASS expr    {
  114.             CODE("argdivassign"); ARGNO($1);
  115.             code2(Ft_argdivassign, (Inst)$1); $$=$3; }
  116.     |    argelement '=' expr     {
  117.             CODE("argvarpush"); ARGNO($1); CODE("eassign");
  118.             code3(Ft_argvarpush, (Inst)$1, Ft_eassign); $$=$3; }
  119.     |    argelement ADDASS expr    {
  120.             CODE("argvarpush"); ARGNO($1); CODE("eaddassign");
  121.             code3(Ft_argvarpush, (Inst)$1, Ft_eaddassign); $$=$3; }
  122.     |    argelement SUBASS expr    {
  123.             CODE("argvarpush"); ARGNO($1); CODE("esubassign");
  124.             code3(Ft_argvarpush, (Inst)$1, Ft_esubassign); $$=$3; }
  125.     |    argelement MULASS expr    {
  126.             CODE("argvarpush"); ARGNO($1); CODE("emulassign");
  127.             code3(Ft_argvarpush, (Inst)$1, Ft_emulassign); $$=$3; }
  128.     |    argelement DIVASS expr    {
  129.             CODE("argvarpush"); ARGNO($1); CODE("edivassign");
  130.             code3(Ft_argvarpush, (Inst)$1, Ft_edivassign); $$=$3; }
  131.     |    element '=' expr     {
  132.             CODE3("varpush", $1->name, "eassign");
  133.             code3(Ft_varpush, (Inst)$1, Ft_eassign); $$=$3; }
  134.     |    element ADDASS expr    {
  135.             CODE3("varpush", $1->name, "eaddassign");
  136.             code3(Ft_varpush, (Inst)$1, Ft_eaddassign); $$=$3; }
  137.     |    element SUBASS expr    {
  138.             CODE3("varpush", $1->name, "esubassign");
  139.             code3(Ft_varpush, (Inst)$1, Ft_esubassign); $$=$3; }
  140.     |    element MULASS expr    {
  141.             CODE3("varpush", $1->name, "emulassign");
  142.             code3(Ft_varpush, (Inst)$1, Ft_emulassign); $$=$3; }
  143.     |    element DIVASS expr    {
  144.             CODE3("varpush", $1->name, "edivassign");
  145.             code3(Ft_varpush, (Inst)$1, Ft_edivassign); $$=$3; }
  146.     ;
  147. strasgn: STRVAR '=' string     {
  148.             CODE3("varpush", $1->name, "strassign");
  149.             code3(Ft_varpush, (Inst)$1, Ft_strassign); $$=$3; }
  150.     |    STRVARARG '=' string     {
  151.             CODE("argvarpush"); ARGNO($1); CODE("strassign");
  152.             code3(Ft_argvarpush, (Inst)$1, Ft_strassign); $$=$3; }
  153.     ;
  154. vecasgn: VEC '=' vecloop expr     {
  155.             CODE3("varpush", $1->name, "assign");
  156.             CODE2("nullpop", "STOP");
  157.             code3(Ft_varpush, (Inst)$1, Ft_assign);
  158.             code2(Ft_nullpop, STOP); }
  159.     |    VEC ADDASS vecloop expr    {
  160.             CODE3("varpush", $1->name, "addassign");
  161.             CODE2("nullpop", "STOP");
  162.             code3(Ft_varpush, (Inst)$1, Ft_addassign);
  163.             code2(Ft_nullpop, STOP); }
  164.     |    VEC SUBASS vecloop expr    {
  165.             CODE3("varpush", $1->name, "subassign");
  166.             CODE2("nullpop", "STOP");
  167.             code3(Ft_varpush, (Inst)$1, Ft_subassign);
  168.             code2(Ft_nullpop, STOP); }
  169.     |    VEC MULASS vecloop expr    {
  170.             CODE3("varpush", $1->name, "mulassign");
  171.             CODE2("nullpop", "STOP");
  172.             code3(Ft_varpush, (Inst)$1, Ft_mulassign);
  173.             code2(Ft_nullpop, STOP); }
  174.     |    VEC DIVASS vecloop expr    {
  175.             CODE3("varpush", $1->name, "divassign");
  176.             CODE2("nullpop", "STOP");
  177.             code3(Ft_varpush, (Inst)$1, Ft_divassign);
  178.             code2(Ft_nullpop, STOP); }
  179.     |    VECARG '=' vecloop expr     {
  180.             CODE("argvarpush"); ARGNO($1); CODE("assign");
  181.             CODE2("nullpop", "STOP");
  182.             code3(Ft_argvarpush, (Inst)$1, Ft_assign);
  183.             code2(Ft_nullpop, STOP); }
  184.     |    VECARG ADDASS vecloop expr    {
  185.             CODE("argvarpush"); ARGNO($1); CODE("addassign");
  186.             CODE2("nullpop", "STOP");
  187.             code3(Ft_argvarpush, (Inst)$1, Ft_addassign);
  188.             code2(Ft_nullpop, STOP); }
  189.     |    VECARG SUBASS vecloop expr    {
  190.             CODE("argvarpush"); ARGNO($1); CODE("subassign");
  191.             CODE2("nullpop", "STOP");
  192.             code3(Ft_argvarpush, (Inst)$1, Ft_subassign);
  193.             code2(Ft_nullpop, STOP); }
  194.     |    VECARG MULASS vecloop expr    {
  195.             CODE("argvarpush"); ARGNO($1); CODE("mulassign");
  196.             CODE2("nullpop", "STOP");
  197.             code3(Ft_argvarpush, (Inst)$1, Ft_mulassign);
  198.             code2(Ft_nullpop, STOP); }
  199.     |    VECARG DIVASS vecloop expr    {
  200.             CODE("argvarpush"); ARGNO($1); CODE("divassign");
  201.             CODE2("nullpop", "STOP");
  202.             code3(Ft_argvarpush, (Inst)$1, Ft_divassign);
  203.             code2(Ft_nullpop, STOP); }
  204.     ;
  205. parasgn: PARAM '=' parloop expr     {
  206.             CODE3("varpush", $1->name, "assign");
  207.             CODE2("nullpop", "STOP");
  208.             code3(Ft_varpush, (Inst)$1, Ft_assign);
  209.             code2(Ft_nullpop, STOP); }
  210.     |    PARAM ADDASS parloop expr    {
  211.             CODE3("varpush", $1->name, "addassign");
  212.             CODE2("nullpop", "STOP");
  213.             code3(Ft_varpush, (Inst)$1, Ft_addassign);
  214.             code2(Ft_nullpop, STOP); }
  215.     |    PARAM SUBASS parloop expr    {
  216.             CODE3("varpush", $1->name, "subassign");
  217.             CODE2("nullpop", "STOP");
  218.             code3(Ft_varpush, (Inst)$1, Ft_subassign);
  219.             code2(Ft_nullpop, STOP); }
  220.     |    PARAM MULASS parloop expr    {
  221.             CODE3("varpush", $1->name, "mulassign");
  222.             CODE2("nullpop", "STOP");
  223.             code3(Ft_varpush, (Inst)$1, Ft_mulassign);
  224.             code2(Ft_nullpop, STOP); }
  225.     |    PARAM DIVASS parloop expr    {
  226.             CODE3("varpush", $1->name, "divassign");
  227.             CODE2("nullpop", "STOP");
  228.             code3(Ft_varpush, (Inst)$1, Ft_divassign);
  229.             code2(Ft_nullpop, STOP); }
  230.     |    PARARG '=' parloop expr     {
  231.             CODE("argvarpush"); ARGNO($1); CODE("assign");
  232.             CODE2("nullpop", "STOP");
  233.             code3(Ft_argvarpush, (Inst)$1, Ft_assign);
  234.             code2(Ft_nullpop, STOP); }
  235.     |    PARARG ADDASS parloop expr    {
  236.             CODE("argvarpush"); ARGNO($1); CODE("addassign");
  237.             CODE2("nullpop", "STOP");
  238.             code3(Ft_argvarpush, (Inst)$1, Ft_addassign);
  239.             code2(Ft_nullpop, STOP); }
  240.     |    PARARG SUBASS parloop expr    {
  241.             CODE("argvarpush"); ARGNO($1); CODE("subassign");
  242.             CODE2("nullpop", "STOP");
  243.             code3(Ft_argvarpush, (Inst)$1, Ft_subassign);
  244.             code2(Ft_nullpop, STOP); }
  245.     |    PARARG MULASS parloop expr    {
  246.             CODE("argvarpush"); ARGNO($1); CODE("mulassign");
  247.             CODE2("nullpop", "STOP");
  248.             code3(Ft_argvarpush, (Inst)$1, Ft_mulassign);
  249.             code2(Ft_nullpop, STOP); }
  250.     |    PARARG DIVASS parloop expr    {
  251.             CODE("argvarpush"); ARGNO($1); CODE("divassign");
  252.             CODE2("nullpop", "STOP");
  253.             code3(Ft_argvarpush, (Inst)$1, Ft_divassign);
  254.             code2(Ft_nullpop, STOP); }
  255.     ;
  256. argelement:    VECARG index     { $$=$1; }
  257.     |    PARARG index     { $$=$1; }
  258.     ;
  259. element: VEC index     { $$=$1; }
  260.     |    PARAM index    { $$=$1; }
  261.     ;
  262. index: '[' expr ']'
  263.     ;
  264. vecloop:    {
  265.             CODE("vecloop");
  266.             $$ = code(Ft_vecloop); }
  267.     ;
  268. parloop:    {
  269.             CODE("parloop");
  270.             $$ = code(Ft_parloop); }
  271.     ;
  272. stmt: strasgn        {
  273.             CODE("nullpop");
  274.             code(Ft_nullpop); }
  275.     | dontprint {
  276.             CODE("nullpop");
  277.             code(Ft_nullpop); }
  278.     | vecasgn
  279.     | parasgn
  280.     | linprlist    {
  281.             CODE("linprnl");
  282.             code(Ft_linprnl); }
  283.     | PRINT prlist     { $$ = $2;}
  284.     | RETURN {
  285.             CODE("procret");
  286.             Ft_defnonly(PROC, "return"); $$ = code(Ft_procret); }
  287.     | RETURN '(' expr ')'    {
  288.             CODE("funcret");
  289.             Ft_defnonly(FUNC, "return"); $$ = $3; code(Ft_funcret); }
  290.     | CONTINUE         {
  291.             CODE("STOP");
  292.             Ft_defnonly(WHILE, "continue"); $$ = code(STOP); }
  293.     | BREAK               {
  294.             CODE("breakit");
  295.             Ft_defnonly(WHILE, "break"); $$ = code(Ft_breakit); }
  296.     | EPROCSYM begin '(' arglist ')'    {
  297.             CODE2("extcall", $1->name); ARGNO($4);
  298.             $$=$2; code3(Ft_extcall, (Inst)$1, (Inst)$4); }
  299.     | PROCSYM begin '(' arglist ')'    {
  300.             CODE2("call", $1->name); ARGNO($4);
  301.             $$=$2; code3(Ft_call, (Inst)$1, (Inst)$4); }
  302.     | while cond newline stmtline end {
  303.             CODE("Replace while[1]"); PNUM($4-prog);
  304.               ($1)[1] = (Inst) $4;
  305.             CODE("Replace while[2]"); PNUM($5-prog);
  306.               ($1)[2] = (Inst) $5; }
  307.     | if cond newline stmtline end newline {
  308.             CODE("Replace if[1]"); PNUM($4-prog);
  309.               ($1)[1] = (Inst) $4;
  310.             CODE("Replace if[3]"); PNUM($5-prog);
  311.               ($1)[3] = (Inst) $5; }
  312.     | if cond newline stmtline end newline else newline stmtline end {
  313.             CODE("Replace if[1]"); PNUM($4-prog);
  314.               ($1)[1] = (Inst) $4;
  315.             CODE("Replace if[2]"); PNUM($9-prog);
  316.               ($1)[2] = (Inst) $9;
  317.             CODE("Replace if[3]"); PNUM($10-prog);
  318.               ($1)[3] = (Inst) $10; }
  319.     | for asgnlist forcond exprlist newline stmtline end {
  320.             CODE("Replace for[1]"); PNUM($2-prog);
  321.               ($1)[1] = (Inst) $2;
  322.             CODE("Replace for[2]"); PNUM($3-prog);
  323.               ($1)[2] = (Inst) $3;
  324.             CODE("Replace for[3]"); PNUM($6-prog);
  325.               ($1)[3] = (Inst) $6;
  326.             CODE("Replace for[4]"); PNUM($7-prog);
  327.               ($1)[4] = (Inst) $7; }
  328.     | opbrace autolines        {
  329.             if ($2) {
  330.                 CODE("boost"); ARGNO($2);
  331.                 code2(Ft_boost, (Inst)$2);
  332.             };                        }
  333.       stmtlist clbrace    { ; }
  334.     ;
  335. newline:
  336.     |    '\n'     { if (!Ft_more_input(Ft_Inbrace, interprompt)) {
  337.                     Ft_matherror("Incomplete statement.", 0, 0);
  338.                    };                        }
  339.     ;
  340. opbrace: '{'  { Ft_Inbrace++; $$ = Ft_Progp; }
  341.     ;
  342. clbrace: '}'  {
  343.                 {     int num = Ft_autosymremove(Ft_Inbrace--);
  344.                     if (num) {
  345.                         CODE("restore"); ARGNO(num);
  346.                         code2(Ft_restore, (Inst)num);
  347.                     };
  348.                 };                         }
  349.     ;
  350. stmtlist: 
  351.     |   stmtlist '\n'    { if (!Ft_more_input(Ft_Inbrace, 0)) {
  352.                             Ft_matherror("Unmatched brace.", 0, 0);
  353.                            };                        }
  354.     |    stmtlist stmtline
  355.     ;
  356. autolines:                    { $$ = 0; }
  357.     |  autol                { $$ = $1; }
  358.     |  autolines ';'        { $$ = $1; }
  359.     |  autolines '\n'       { $$ = $1; 
  360.                             if (!Ft_more_input(Ft_Inbrace, 0)) {
  361.                                 Ft_matherror("Unmatched brace.", 0, 0);
  362.                             };                        }
  363.     |  autolines autol        { $$ = $1 + $2; }
  364.     ;
  365. autol:  AUTO                 { Ft_Inauto = 1; }
  366.         autolist            { Ft_Inauto = 0; $$ = $3; }
  367.     ;
  368. autolist:     VARARG                 {
  369.             CODE2("pushnull", "pushexprtype");
  370.             code2(Ft_pushnull, Ft_pushexprtype); $$ = 1; }
  371.     |    VARARG '='             { Ft_Inauto = 0; }
  372.         expr                {
  373.             CODE("pushexprtype");
  374.             code(Ft_pushexprtype); $$ = 1; Ft_Inauto = 1; }
  375.     |    STRVARARG            {
  376.             CODE2("strmake", "pushastrtype");
  377.             code2(Ft_strmake, Ft_pushastrtype); $$ = 1; }
  378.     |    VECARG                 {
  379.             CODE2("vecmake", "pushavectype");
  380.             code2(Ft_vecmake, Ft_pushavectype); $$ = 1; }
  381.     |    autolist ',' VARARG    {
  382.             CODE2("pushnull", "pushexprtype");
  383.             code2(Ft_pushnull, Ft_pushexprtype); $$ = $1 + 1; }
  384.     |    autolist ',' VARARG '='         { Ft_Inauto = 0; }
  385.         expr                {
  386.             CODE("pushexprtype");
  387.             code(Ft_pushexprtype); Ft_Inauto = 1; $$ = $1 + 1; }
  388.     |    autolist ',' VECARG    {
  389.             CODE2("vecmake", "pushavectype");
  390.             code2(Ft_vecmake, Ft_pushavectype); $$ = $1 + 1; }
  391.     |    autolist ',' STRVARARG     {
  392.             CODE2("stramke", "pushastrtype");
  393.             code2(Ft_strmake, Ft_pushastrtype); $$ = $1 + 1; }
  394.     ;
  395. cond: '(' expr ')'      {
  396.             CODE("STOP");
  397.             code(STOP); $$=$2; }
  398.     ;
  399. asgnlist:    '(' asgnl     {
  400.             CODE("STOP");
  401.             code(STOP); $$=Ft_Progp; }
  402.     ;
  403. asgnl:   asgn    {
  404.             CODE("nullpop");
  405.             code(Ft_nullpop); }
  406.     |    strasgn    {
  407.             CODE("nullpop");
  408.             code(Ft_nullpop); }
  409.     |    vecasgn
  410.     |    parasgn
  411.     |    asgnl ',' asgn    {
  412.             CODE("nullpop");
  413.             code(Ft_nullpop); }
  414.     |    asgnl ',' strasgn    {
  415.             CODE("nullpop");
  416.             code(Ft_nullpop); }
  417.     |    asgnl ',' vecasgn
  418.     |    asgnl ',' parasgn
  419.     ;
  420. forcond:     ';' expr ';'    {
  421.             CODE("STOP");
  422.             code(STOP);  $$=Ft_Progp; }
  423.         ;
  424. exprlist:    exprl ')'    {
  425.             CODE("STOP");
  426.             code(STOP); }
  427.     ;
  428. exprl:   expr    {
  429.             CODE("nullpop");
  430.             code(Ft_nullpop); }
  431.     |    string  {
  432.             CODE("nullpop");
  433.             code(Ft_nullpop); }
  434.     |     vecasgn
  435.     |     parasgn
  436.     |    exprl ',' expr    {
  437.             CODE("nullpop");
  438.             code(Ft_nullpop); }
  439.     |    exprl ',' string  {
  440.             CODE("nullpop");
  441.             code(Ft_nullpop); }
  442.     |    exprl ',' vecasgn
  443.     |    exprl ',' parasgn
  444.     ;
  445. while:   WHILE             {
  446.             CODE3("whilecode", "STOP", "STOP");
  447.             $$ = code3(Ft_whilecode, STOP, STOP); 
  448.             interprompt = "while? "; }
  449.     ;
  450. if:      IF                 {
  451.             CODE("ifcode"); CODE3("STOP", "STOP", "STOP");
  452.             $$ = code(Ft_ifcode); code3(STOP, STOP, STOP);
  453.             interprompt = "if? "; }
  454.     ;
  455. else:     ELSE                {
  456.             interprompt = "else? "; }
  457.     ;
  458. for:     FOR                {
  459.             CODE("forcode"); CODE("STOP"); CODE3("STOP", "STOP", "STOP");
  460.             $$ = code(Ft_forcode); code(STOP); code3(STOP, STOP, STOP);
  461.             interprompt = "for? "; }
  462.     ;
  463. begin:                  { $$ = Ft_Progp; }
  464.     ;
  465. end:                    {
  466.             CODE("STOP");
  467.             code(STOP); $$ = Ft_Progp; }
  468.     ;
  469. dontprint: varincr
  470.     | asgn
  471.     ;
  472. expr: argexpr
  473.     | VEC        {
  474.             CODE3("varpush", $1->name, "eval");
  475.             $$ = code3(Ft_varpush, (Inst)$1, Ft_eval); }
  476.     | VECARG     {
  477.             CODE("argvarpush"); ARGNO($1); CODE("eval");
  478.             $$ = code3(Ft_argvarpush, (Inst)$1, Ft_eval); }
  479.     ;
  480. argexpr: value
  481.     | dontprint
  482.     ;
  483. argstr: STRVAR        {
  484.             CODE2("varpush", $1->name);
  485.             $$ = code2(Ft_varpush, (Inst)$1); }
  486.     | UNDEFSTRVAR        {
  487.             CODE2("varpush", $1->name);
  488.             $$ = code2(Ft_varpush, (Inst)$1); }
  489.     ;
  490. nicevec: VEC           {
  491.             CODE2("varpush", $1->name);
  492.             $$ = code2(Ft_varpush, (Inst)$1); }
  493.     ;
  494. argvec: nicevec
  495.     | UNDEFVEC        {
  496.             CODE2("varpush", $1->name);
  497.             $$ = code2(Ft_varpush, (Inst)$1); }
  498.     ;
  499. argpar: PARAM          {
  500.             CODE2("varpush", $1->name);
  501.             $$ = code2(Ft_varpush, (Inst)$1); }
  502.     ;
  503. varincr:INCR VAR %prec INCR {
  504.             CODE3("varpush", $2->name, "preieval");
  505.             $$ = code3(Ft_varpush, (Inst)$2, Ft_preieval); }
  506.     |    VAR INCR %prec INCR {
  507.             CODE3("varpush", $1->name, "postieval");
  508.             $$ = code3(Ft_varpush, (Inst)$1, Ft_postieval); }
  509.     |    DECR VAR %prec INCR {
  510.             CODE3("varpush", $2->name, "predeval");
  511.             $$ = code3(Ft_varpush, (Inst)$2, Ft_predeval); }
  512.     |    VAR DECR %prec INCR {
  513.             CODE3("varpush", $1->name, "postdeval");
  514.             $$ = code3(Ft_varpush, (Inst)$1, Ft_postdeval); }
  515.     |    INCR VARARG %prec INCR {
  516.             CODE("preiargpush"); ARGNO($2);
  517.             $$ = code2(Ft_preiargpush, (Inst)$2); }
  518.     |    VARARG INCR %prec INCR {
  519.             CODE("postiargpush"); ARGNO($1);
  520.             $$ = code2(Ft_postiargpush, (Inst)$1); }
  521.     |    DECR VARARG %prec INCR {
  522.             CODE("predargpush"); ARGNO($2);
  523.             $$ = code2(Ft_predargpush, (Inst)$2); }
  524.     |    VARARG DECR %prec INCR {
  525.             CODE("postdargpush"); ARGNO($1);
  526.             $$ = code2(Ft_postdargpush, (Inst)$1); }
  527.     ;
  528. value: NUMBER    {
  529.             CODE2("constpush", "number");
  530.             $$ = code(Ft_constpush); Ft_dblcode($1); }
  531.     | VARARG        {
  532.             CODE("argpush"); ARGNO($1);
  533.             $$ = code2(Ft_argpush, (Inst)$1); }
  534.     | VAR        {
  535.             CODE3("varpush", $1->name, "eval");
  536.             $$ = code3(Ft_varpush, (Inst)$1, Ft_eval); }
  537.     | CONST        {
  538.             CODE3("varpush", $1->name, "eval");
  539.             $$ = code3(Ft_varpush, (Inst)$1, Ft_eval); }
  540.     | EFUNCSYM begin '(' arglist ')'    {
  541.             CODE2("extcall", $1->name); ARGNO($4);
  542.             $$ = $2; code3(Ft_extcall, (Inst)$1, (Inst)$4); }
  543.     | FUNCSYM begin '(' arglist ')'    {
  544.             CODE2("call", $1->name); ARGNO($4);
  545.             $$ = $2; code3(Ft_call, (Inst)$1, (Inst)$4); }
  546.     | BLTIN0  '(' ')' {
  547.             CODE2("builtin0", $1->name);
  548.             $$ = code2(Ft_bltin0, (Inst)$1->u.ptr); }
  549.     | BLTIN1VEC '(' nicevec ')' {
  550.             CODE2("builtin1vec", $1->name);
  551.             $$ = code2(Ft_bltin1vec, (Inst)$1->u.ptr); }
  552.     | BLTIN1  '(' expr ')' {
  553.             CODE2("builtin1", $1->name);
  554.             $$ = code2(Ft_bltin1, (Inst)$1->u.ptr); }
  555.     | BLTIN2  '(' expr ',' expr ')' {
  556.             CODE2("builtin2", $1->name);
  557.             $$ = code2(Ft_bltin2, (Inst)$1->u.ptr); }
  558.     | STRBLTIN2  '(' string ',' string ')' {
  559.             CODE2("strbltin2", $1->u.str);
  560.             $$ = code2(Ft_strbltin2, (Inst)$1->u.str); }
  561.     | element         {
  562.             CODE3("varpush", $1->name, "eeval");
  563.             $$ = code3(Ft_varpush, (Inst)$1, Ft_eeval); }
  564.     | argelement      {
  565.             CODE("argvarpush"); ARGNO($1); CODE("eeval");
  566.             $$ = code3(Ft_argvarpush, (Inst)$1, Ft_eeval); }
  567.     | '(' expr ')'     { $$ = $2;    }
  568.     | expr '+' expr {
  569.             CODE("add");
  570.             code(Ft_add); }
  571.     | expr '-' expr {
  572.             CODE("sub");
  573.             code(Ft_sub); }
  574.     | expr '/' expr {
  575.             CODE("div");
  576.             code(Ft_div); }
  577.     | expr '%' expr {
  578.             CODE("modulo");
  579.             code(Ft_modulo); }
  580.     | expr '*' expr {
  581.             CODE("mul");
  582.             code(Ft_mul); }
  583.     | expr '^' expr {
  584.             CODE("power");
  585.             code(Ft_power); }
  586.     | '-' expr %prec UNARYMINUS {
  587.             CODE("negate");
  588.             $$ = $2; code(Ft_negate); }
  589.     | string EQ string  {
  590.             CODE("streq");
  591.             code(Ft_streq);  }
  592.     | string NE string  {
  593.             CODE("strne");
  594.             code(Ft_strne);  }
  595.     | expr GT expr  {
  596.             CODE("gt");
  597.             code(Ft_gt); }
  598.     | expr GE expr {
  599.             CODE("ge");
  600.             code(Ft_ge); }
  601.     | expr LT expr  {
  602.             CODE("lt");
  603.             code(Ft_lt);  }
  604.     | expr LE expr  {
  605.             CODE("le");
  606.             code(Ft_le);  }
  607.     | expr EQ expr  {
  608.             CODE("eq");
  609.             code(Ft_eq);  }
  610.     | expr NE expr  {
  611.             CODE("ne");
  612.             code(Ft_ne);  }
  613.     | expr AND expr {
  614.             CODE("and");
  615.             code(Ft_and); }
  616.     | expr OR expr  {
  617.             CODE("or");
  618.             code(Ft_or);  }
  619.     | NOT expr      {
  620.             CODE("not");
  621.             $$ = $2; code(Ft_not); }
  622.     ;
  623. string: strvalue
  624.     | strasgn
  625.     ;
  626. strvalue: STRING    {
  627.             CODE2("strpush", "string");
  628.             $$ = code2(Ft_strpush, (Inst)$1); }
  629.     | STRVAR        {
  630.             CODE3("varpush", $1->name, "streval");
  631.             $$ = code3(Ft_varpush, (Inst)$1, Ft_streval); }
  632.     | STRVARARG     {
  633.             CODE("argvarpush"); ARGNO($1); CODE("streval");
  634.             $$ = code3(Ft_argvarpush, (Inst)$1, Ft_streval); }
  635.     | STRCONST      {
  636.             CODE3("varpush", $1->name, "streval");
  637.             $$ = code3(Ft_varpush, (Inst)$1, Ft_streval); }
  638.     | BLTIN2STR '(' string ',' string ')'    {
  639.             CODE2("builtin2str", $1->name);
  640.             code2(Ft_bltin2str, (Inst)$1->u.ptr); }
  641.     | BLTIN1STR '(' string ')' {
  642.             CODE2("builtin1str", $1->name);
  643.             code2(Ft_bltin1str, (Inst)$1->u.ptr); }
  644.     | BLTIN0STR '(' ')'        {
  645.             CODE2("builtin0str", $1->name);
  646.             code2(Ft_bltin0str, (Inst)$1->u.ptr); }
  647.     | string '-' string        {
  648.         CODE("strsub");
  649.         code(Ft_strsub); }
  650.     | string '+' string        {
  651.         CODE("stradd");
  652.         code(Ft_stradd); }
  653.     | '(' string ')'     { $$ = $2; }
  654.     ;
  655. defn:    FUNC procname { Ft_chkfunc(FUNCSYM, $2); Ft_Indef=1; }
  656.         '(' { Ft_Inproto = 1; Ft_autosymremove(0); }
  657.         protolist ')' { Ft_Inproto = 0; CODE("STOP"); code(STOP); }
  658.         stmt    {
  659.             CODE("procret");
  660.             code(Ft_procret); Ft_define($2); Ft_Indef = 0;
  661.             Ft_autosymremove(0); }
  662.     |    PROC procname { Ft_chkfunc(PROCSYM, $2); Ft_Indef=1; }
  663.         '(' { Ft_Inproto = 1; Ft_autosymremove(0); }
  664.         protolist ')' { Ft_Inproto = 0; CODE("STOP"); code(STOP); }
  665.         stmt    {
  666.             CODE("procret");
  667.             code(Ft_procret); Ft_define($2); Ft_Indef = 0;
  668.             Ft_autosymremove(0); }
  669.     ;
  670. procname: VAR
  671.         | FUNCSYM
  672.         | PROCSYM
  673.         ;
  674. protolist:
  675.     | VARARG { CODE("NUMBER"); code((Inst)NUMBER); }
  676.     | VECARG { CODE("VEC"); code((Inst)VEC); }
  677.     | PARARG { CODE("PARAM"); code((Inst)PARAM); }
  678.     | STRVARARG { CODE("STRVAR"); code((Inst)STRVAR); }
  679.     | protolist ',' VARARG { CODE("NUMBER"); code((Inst)NUMBER); }
  680.     | protolist ',' VECARG { CODE("VEC"); code((Inst)VEC); }
  681.     | protolist ',' PARARG { CODE("PARAM"); code((Inst)PARAM); }
  682.     | protolist ',' STRVARARG { CODE("STRVAR"); code((Inst)STRVAR); }
  683.     ;
  684. arglist:                { $$ = 0; }
  685.     | argpar            { CODE("pushpartype"); code(Ft_pushpartype); $$ = 1; }
  686.     | argvec            { CODE("pushvectype"); code(Ft_pushvectype); $$ = 1; }
  687.     | argstr            { CODE("pushstrtype"); code(Ft_pushstrtype); $$ = 1; }
  688.     | argexpr           { CODE("pushexprtype"); code(Ft_pushexprtype); $$ = 1; }
  689.     | arglist ',' argpar  { CODE("pushpartype"); code(Ft_pushpartype);
  690.                             $$ = $1 + 1; }
  691.     | arglist ',' argvec  { CODE("pushvectype"); code(Ft_pushvectype);
  692.                             $$ = $1 + 1; }
  693.     | arglist ',' argstr  { CODE("pushstrtype"); code(Ft_pushstrtype);
  694.                             $$ = $1 + 1; }
  695.     | arglist ',' argexpr { CODE("pushexprtype"); code(Ft_pushexprtype);
  696.                             $$ = $1 + 1; }
  697.     ;
  698. linprlist:    value          {
  699.             CODE("linprexpr");
  700.             code(Ft_linprexpr); }
  701.     | strvalue               {
  702.             CODE("linprstr");
  703.             code(Ft_linprstr);  }
  704.     | linprlist ',' value    {
  705.             CODE("linprexpr");
  706.             code(Ft_linprexpr); }
  707.     | linprlist ',' strvalue {
  708.             CODE("linprstr");
  709.             code(Ft_linprstr);  }
  710.     ;
  711. prlist:     expr          {
  712.             CODE("prexpr");
  713.             code(Ft_prexpr); }
  714.     | string              {
  715.             CODE("prstr");
  716.             code(Ft_prstr);  }
  717.     | prlist ',' expr     {
  718.             CODE("prexpr");
  719.             code(Ft_prexpr); }
  720.     | prlist ',' string   {
  721.             CODE("prstr");
  722.             code(Ft_prstr);  }
  723.     ;
  724. %%
  725.  
  726.